﻿using SimpleInjector;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.Compilation;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.UI;
using XT.BusinessService;
using XT.Model;
using XT.Repository;


namespace XT.Web
{
    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit http://go.microsoft.com/?LinkId=9394801
    public class MvcApplication : System.Web.HttpApplication
    {
        private static Container _container;
         
        [System.Diagnostics.DebuggerStepThrough]
        public static TService GetInstance<TService>()
            where TService : class
        {
            return _container.GetInstance<TService>();
        }

        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);

            Bootstrap();
        }

        private static void Bootstrap()
        {
            // 1. Create a new Simple Injector container
            var container = new Container();

            // 2. Configure the container (register)
            var uow = new Uow(new XomtroDataContext(ConfigurationManager.ConnectionStrings["XOMTROConnectionString"].ConnectionString)); 
            container.RegisterSingle<IUow>(uow);

            //container.RegisterSingle<IAccountService>(() => new AccountService(uow));

            container.RegisterSingle<ICityService>(() => new CityService(uow));
            container.RegisterSingle<IRoomService>(() => new RoomService(uow));
            container.RegisterSingle<IDistrictService>(() => new DistrictService(uow));
            container.RegisterSingle<IAreaService>(() => new AreaService(uow));
            container.RegisterSingle<IAccountService>(() => new AccountService(uow));
            container.RegisterSingle<IRoomReviewService>(()=>new RoomReviewService(uow));
            container.RegisterSingle<IRoomListService>(() => new RoomListService(uow));
            container.RegisterSingle<IAmentityService>(() => new AmentityService(uow));
            container.RegisterSingle<IUtilityPlaceService>(() => new UtilityPlaceService(uow));
            //container.RegisterSingle<IShopService>(() => new ShopService(uow));

            // 3. Optionally verify the container's configuration.
            container.Verify();
            VerifyPages(container);

            // 4. Store the container for use by Page classes.
            _container = container;
        }

        private static void VerifyPages(Container container)
        {
            var assemblies = BuildManager.GetReferencedAssemblies().Cast<Assembly>();

            var pageTypes =
                assemblies.SelectMany(assembly => assembly.GetExportedTypes(), (assembly, type) => new { assembly, type })
                          .Where(@t => typeof(Page).IsAssignableFrom(@t.type))
                          .Where(@t => !@t.type.IsAbstract)
                          .Select(@t => @t.type);

            //foreach (var pageType in pageTypes)
            //{
            //    container.GetInstance(pageType);
            //}
        }
    }
}